package com.gaojinqi.apigateway.filter;

import com.gaojinqi.apigateway.exception.RateLimitException;
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;

/**
 * 限流过滤器
 *
 * @author gaojinqi
 * @date 2019/5/30 0:05
 */
public class RateLimitFilter extends ZuulFilter {

    /**
     * Google开源Guava令牌桶限流算法
     */
    private static final RateLimiter RATE_LIMITER = RateLimiter.create(100);

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    // 过滤器调用顺序，越小越先调用
    @Override
    public int filterOrder() {
        // 时机：请求被转发之前调用，要在所有过滤器之前被执行
        return SERVLET_DETECTION_FILTER_ORDER - 1;
    }

    // 返回一个boolean值来判断该过滤器是否要执行
    @Override
    public boolean shouldFilter() {
        return true;
    }

    // 过滤器的具体逻辑
    @Override
    public Object run() throws ZuulException {
        if (RATE_LIMITER.tryAcquire()) {
            throw new RateLimitException();
        }
        return null;
    }
}
